package com.kfyang.manualgear.util;


import com.kfyang.manualgear.annotation.global.Mapper;
import com.kfyang.manualgear.annotation.global.ResultHandler;
import com.kfyang.manualgear.struct.Page;
import com.kfyang.manualgear.struct.PageResult;
import com.kfyang.manualgear.struct.PageResultImpl;
import com.kfyang.manualgear.struct.Sort;

import java.util.List;
import java.util.Map;
import java.util.function.Function;

public interface ResultUtils {
    /**
     * 处理裸类型
     * @param oneFunction jdbcTemplate调用后返回单值的方法
     * @param sql 拼装后的sql语句
     * @return 结果
     * @param <T> 处理类型
     */
    @ResultHandler
    static <T> T originResult(Function<String, T> oneFunction,
                              StringBuilder sql) {
        return oneFunction.apply(sql.toString());
    }

    /**
     * 处理List类型
     * @param manyFunction jdbcTemplate调用后返回多值的方法
     * @param sql 拼装后的sql语句
     * @return 结果
     * @param <T> 处理类型
     */
    @ResultHandler
    static <T> List<T> listResult(Function<String, List<T>> manyFunction,
                                  StringBuilder sql) {
        return manyFunction.apply(sql.toString());
    }

    /**
     * 处理分页类型
     * @param countFunction count方法调用
     * @param manyFunction jdbcTemplate调用后返回多值的方法
     * @param sql 拼装后的sql语句
     * @param page 分页信息
     * @return 结果
     * @param <T> 处理类型
     */
    @ResultHandler
    static <T> PageResult<T> pageResult(
        @Mapper(value = "(rs, rowNum) -> rs.getInt(\"c1\")", forOne = true) Function<String, Integer> countFunction,
        Function<String, List<T>> manyFunction,
        StringBuilder sql, Page page) {
        String countSql = "select count(*) c1 " + sql.substring(sql.indexOf("from"));

        List<Sort> sortList = page.getSortList();
        if (!sortList.isEmpty()) {
            sql.append(" order by ");
            for (int i = 0; i < sortList.size(); i++) {
                Sort sort = sortList.get(i);
                sql.append(sort.getField())
                    .append(sort.getOrder() == Sort.Order.ASC ? " asc " : " desc ");
                if (i != sortList.size() - 1) {
                    sql.append(",");
                }
            }
        }
        // 分页
        sql.append(" limit ");
        sql.append(page.getSize() * page.getPage());
        sql.append(",");
        sql.append(page.getSize());

        List<T> queryResult = manyFunction.apply(sql.toString());
        Integer total = countFunction.apply(countSql);
        return new PageResultImpl<>(page.getPage(), total, queryResult);
    }
}
